<?php
namespace app\admin\model;

use app\common\model\Config;

class WechatPay
{
    /**
     * @param $payment
     * @param $money
     * @param $openid
     * @功能说明:新版商家付款到零钱 2025.1.18更新
     */
    public function createMchPay($openid, $money, $payment,$batch_no)
    {
        $url = 'https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills'; // 新版地址

        $pars = [
            'appid' => $payment['wechat_pay']['app_id'], // 直连商户的appid
            'out_bill_no' => $batch_no, // 商户单号
            'transfer_scene_id' => '1000', // 转账场景ID
            'openid' => $openid, // 收款用户OpenID
            'transfer_amount' => (int)$money * 100, // 转账金额
            'transfer_remark' => '商家转账', // 转账备注
            'user_recv_perception' => '现金奖励', // 用户收款感知
            'transfer_scene_report_infos' => [
                [
                    'info_type' => '活动名称',
                    'info_content' => '申请提现',
                ],
                [
                    'info_type' => '奖励说明',
                    'info_content' => '申请提现',
                ],
            ], // 转账明细列表
        ];

        $token = $this->getToken($pars, $payment, 'POST', $url);
        $res = $this->http_post($url, json_encode($pars), $token, $payment, 1); // 发送请求
        $resArr = json_decode($res, true);

        if (!empty($resArr['code'])) {
            $resArr['result_code'] = $resArr['return_code'] = 'fail';
            $resArr['err_code_des'] = $resArr['message'];
        } else {
            $resArr['result_code'] = $resArr['return_code'] = 'SUCCESS';
        }

        return $resArr;
    }

    /**
     * @param $pars
     * @param $payment
     * @param string $http_method
     * @param string $url
     * @功能说明:获取token
     */
    public function getToken($pars, $payment, $http_method = 'POST', $url = '')
    {
        $timestamp = time(); // 请求时间戳
        $nonce = $timestamp . rand(10000, 99999); // 请求随机串
        $body = !empty($pars) ? json_encode((object)$pars) : ''; // 请求报文主体

        $apiclient_cert_path = $payment['wechat_pay']['cert_path'];
        $apiclient_key_path = $payment['wechat_pay']['key_path'];
        $apiclient_cert_arr = openssl_x509_parse(file_get_contents($apiclient_cert_path));
        $serial_no = $apiclient_cert_arr['serialNumberHex']; // 证书序列号
        $mch_private_key = file_get_contents($apiclient_key_path); // 密钥
        $merchant_id = $payment['wechat_pay']['mch_id']; // 商户id

        $url_parts = parse_url($url); // 获取请求的绝对URL
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $message = $http_method . "\n" .
            $canonical_url . "\n" .
            $timestamp . "\n" .
            $nonce . "\n" .
            $body . "\n";

        openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
        $sign = base64_encode($raw_sign); // 签名
        $schema = 'WECHATPAY2-SHA256-RSA2048';
        $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            $merchant_id, $nonce, $timestamp, $serial_no, $sign); // 微信返回token

        return $token;
    }

    /**
     * POST 请求
     */
    private function http_post($url, $data, $token, $payment, $Wechatpay = 0)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, (string)$url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

        $headers = [
            'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $token,
            'Accept: application/json',
            'Content-Type: application/json; charset=utf-8',
            'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
        ];

        if ($Wechatpay == 1) {
            $certificates = $this->get_Certificates($payment);
            $headers[] = 'Wechatpay-Serial:' . $certificates;
        }

        if (!empty($headers)) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        }

        $output = curl_exec($curl);
        curl_close($curl);

        return $output;
    }

    /**
     * @param $payment
     * @功能说明:获取证书序列号
     */
    public function get_Certificates($payment)
    {
        $platformCertificateFilePath = $payment['wechat_pay']['cert_path'];
        if (empty($platformCertificateFilePath)) {
            return '';
        }

        $a = openssl_x509_parse(file_get_contents($platformCertificateFilePath));
        return !empty($a['serialNumberHex']) ? $a['serialNumberHex'] : '';
    }
}
